String getPartOfSpeechAbbreviation(String fullForm) {
  const Map<String, String> posMap = {
    // 基础词性
    'noun': 'n.',
    'verb': 'v.',
    'adjective': 'adj.',
    'adverb': 'adv.',
    'pronoun': 'pron.',
    'preposition': 'prep.',
    'conjunction': 'conj.',
    'interjection': 'interj.',
    'determiner': 'det.',
    'exclamation': 'excl.',
    'article': 'art.',

    // 动词分类
    'auxiliary verb': 'aux.',
    'modal verb': 'modal v.',
    'phrasal verb': 'phr. v.',
    'transitive verb': 'v.t.',
    'intransitive verb': 'v.i.',

    // 名词分类
    'proper noun': 'prop. n.',
    'common noun': 'comm. n.',
    'countable noun': 'cn.',
    'uncountable noun': 'un.',
    'collective noun': 'coll. n.',

    // 代词分类
    'relative pronoun': 'rel. pron.',
    'personal pronoun': 'pers. pron.',
    'possessive pronoun': 'poss. pron.',
    'demonstrative pronoun': 'dem. pron.',
    'interrogative pronoun': 'interr. pron.',

    // 其他词性
    'numeral': 'num.',
    'particle': 'part.',
    'prefix': 'pref.',
    'suffix': 'suff.',
    'abbreviation': 'abbr.',
    'acronym': 'acr.',
    'gerund': 'ger.',
    'infinitive': 'inf.',
    'participle': 'part.',
    'present participle': 'pres. part.',
    'past participle': 'past part.',
    'definite article': 'def. art.',
    'indefinite article': 'indef. art.',
  };

  final normalizedForm = fullForm.toLowerCase().trim();

  // 直接匹配
  if (posMap.containsKey(normalizedForm)) {
    return posMap[normalizedForm]!;
  }

  // 处理复数形式
  if (normalizedForm.endsWith('s') && normalizedForm.length > 1) {
    final singularForm = normalizedForm.substring(0, normalizedForm.length - 1);
    if (posMap.containsKey(singularForm)) {
      return posMap[singularForm]!;
    }
  }

  // 处理带连字符/空格的复合词性
  final normalizedWithSpace = normalizedForm.replaceAll('-', ' ');
  if (normalizedWithSpace != normalizedForm) {
    if (posMap.containsKey(normalizedWithSpace)) {
      return posMap[normalizedWithSpace]!;
    }
  }

  // 处理缩写形式（如 "adj." → "adj."）
  if (normalizedForm.endsWith('.') && normalizedForm.length > 1) {
    final stripped = normalizedForm.substring(0, normalizedForm.length - 1);
    if (posMap.containsKey(stripped)) {
      return posMap[stripped]!;
    }
  }

  // 未定义情况返回原数据
  return fullForm;
}